/* 
 * File:   DirectedGraph.hpp
 * Author: RaF
 *
 * Created on 2 dicembre 2012, 19.41
 */

#ifndef DIRECTEDGRAPH_HPP
#define	DIRECTEDGRAPH_HPP
#include <vector>
#include <list>
#include <map>
#include "Edge.hpp"
#include "Vertex.hpp"
#include "Graph.h"
/**
 * Classe per la gestione di un grafo orientato
 */
template <typename I> class DirectedGraph : public SimpleGraph<I> {
public:
    DirectedGraph(): SimpleGraph<I>() {}
    DirectedGraph(const DirectedGraph& orig): SimpleGraph<I>(){}
    ~DirectedGraph(){}
    void removeVertex(Vertex<I>* v);
    void insertEdge(Vertex<I>* v, Vertex<I>* w, int edgeWeight);
    void removeEdge(Edge<I>* e);
};


template <typename I> void DirectedGraph<I>::insertEdge(Vertex<I>* v, Vertex<I>* w, int edgeWeight) {
    Edge<I>* fromVtoW = new Edge<I > (v, w, edgeWeight);
    v->getAdjacencyList()->push_back(fromVtoW);
}

template <typename I> void DirectedGraph<I>::removeEdge(Edge<I>* e) {
    //elimino l'arco (u,v)
    int index = this->searchVertex(e->getFrom()->getLabel());
    std::list<Edge<I>*>* list = this->vertices->at(index)->getAdjacencyList();
    bool deleted = false;
    typename std::list<Edge<I>*>::iterator it = list->begin();
    while (!deleted && it != list->end()) {
        if ((*it)->getTo()->getLabel() == e->getTo()->getLabel()) {
            list->erase(it);
            deleted = true;
        }
        ++it;
    }
}

template <typename I> void DirectedGraph<I>::removeVertex(Vertex<I>* v) {
    int labelToRemove = v->getLabel();
    bool deleted = false;
    //cerco nodo da eliminare
    int index = this->searchVertex(labelToRemove);

    if (index>-1) {
        //elimino prima gli archi entranti nel nodo da eliminare
        std::list<Edge<I>*>* list;
        typename std::list<Edge<I>*>::iterator it;
        for (int i = 0; i < this->vertices->size(); i++) {
            list = this->vertices->at(i)->getAdjacencyList();
            it = list->begin();
            while (!deleted && it != list->end()) {
                if ((*it)->getTo()->getLabel() == labelToRemove) {
                    list->erase(it);
                    deleted = true;
                }
                ++it;
            }
        }
        
        //elimino l'elemento dal vettore dei vertici e la sua lista di adiacenza
        typename std::vector<Vertex<I>*>::iterator verticesIt = this->vertices->begin();
        std::advance(verticesIt, index);
        this->vertices->erase(verticesIt);

    }
}
#endif	/* DIRECTEDGRAPH_HPP */

